package com.cmc6.user.service.impl;

import com.cmc6.common.constant.BaseConstant;
import com.cmc6.common.util.ParamUtil;
import com.cmc6.user.model.dto.PhoneNotBlankDTO;
import com.cmc6.user.model.dto.RegByPhoneDTO;
import com.cmc6.user.model.dto.UserLoginInsertOrUpdateDTO;
import com.cmc6.user.service.RegByPhoneService;
import com.cmc6.user.service.UserRegHelperService;
import com.cmc6.user.service.UserService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class RegByPhoneServiceImpl implements RegByPhoneService {

    @Resource
    RedissonClient redissonClient;
    @Resource
    UserRegHelperService userRegHelperService;
    @Resource
    UserService userService;

    /**
     * 注册
     */
    @Override
    @Transactional
    public String regByPhone(RegByPhoneDTO dto) {

        // 非对称加密，解密 ↓
        String paramValue = ParamUtil.getValueById(BaseConstant.RSA_PRIVATE_KEY_ID); // 获取非对称加密，私钥
        dto.setOrigPassword(userService.rsaDecrypt(dto.getOrigPassword(), paramValue)); // 非对称加密：解密
        dto.setPassword(userService.rsaDecrypt(dto.getPassword(), paramValue)); // 非对称加密：解密
        // 非对称加密，解密 ↑

        userService.checkOrigPassword(dto.getOrigPassword()); // 检查密码是否合法

        String key = BaseConstant.PRE_LOCK_PHONE_REG_CODE + dto.getPhone();
        // 增加分布式锁
        // 获取一把锁，只要锁名字一样，就是同一把锁，即：同一时间只能有一个手机进行 注册/修改
        RLock lock = redissonClient.getLock(BaseConstant.PRE_REDISSON + key);
        lock.lock();

        try {
            // 校验 code
            userRegHelperService.checkCodeByRedis(key, dto.getCode());
            regByPhoneNext(dto);
            return "注册成功";
        } finally {
            // 解除分布式锁
            lock.unlock();
        }
    }

    /**
     * 往数据库插入 注册的数据
     */
    private void regByPhoneNext(RegByPhoneDTO dto) {

        UserLoginInsertOrUpdateDTO userLoginInsertOrUpdateDTO = new UserLoginInsertOrUpdateDTO();
        userLoginInsertOrUpdateDTO.setEmail("");
        userLoginInsertOrUpdateDTO.setPassword(dto.getPassword());
        userLoginInsertOrUpdateDTO.setPhone(dto.getPhone());

        userRegHelperService.regBase(userLoginInsertOrUpdateDTO, false);

    }

    /**
     * 发送验证码
     */
    @Override
    public String sendCode(PhoneNotBlankDTO dto) {

        return userRegHelperService.phoneSendCode(dto.getPhone(), 1);
    }

}
